---
apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana
  namespace: {{ .Namespace }}
  labels:
    app: grafana
data:
  grafana.ini: |
    [analytics]
    check_for_updates = true
    [grafana_net]
    url = https://grafana.net
    [log]
    mode = console
    [paths]
    data = /var/lib/grafana/data
    logs = /var/log/grafana
    plugins = /var/lib/grafana/plugins
    provisioning = /etc/grafana/provisioning
    [plugins]
    # Required until we have grafana sign our plugin.
    allow_loading_unsigned_plugins = "kumahq-kuma-datasource"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: provisioning-datasource
  namespace: {{ .Namespace }}
  labels:
    app: grafana
data:
  datasource.yaml: |
    # config file version
    apiVersion: 1

    # list of datasources that should be deleted from the database
    deleteDatasources:
      - name: Prometheus
        orgId: 1

    # list of datasources to insert/update depending
    # whats available in the database
    datasources:
      # <string, required> name of the datasource. Required
      - name: Prometheus
        uid: prometheus
        # <string, required> datasource type. Required
        type: prometheus
        # <string, required> access mode. direct or proxy. Required
        access: proxy
        # <int> org id. will default to orgId 1 if not specified
        orgId: 1
        # <string> url
        url: {{.PrometheusAddress}}
        # <string> database password, if used
        password:
        # <string> database user, if used
        user:
        # <string> database name, if used
        database:
        # <bool> enable/disable basic auth
        basicAuth: false
        # <string> basic auth username, if used
        basicAuthUser:
        # <string> basic auth password, if used
        basicAuthPassword:
        # <bool> enable/disable with credentials headers
        withCredentials:
        # <bool> mark as default datasource. Max one per org
        isDefault: true
        # <map> fields that will be converted to json and stored in json_data
        jsonData:
          graphiteVersion: "1.1"
          tlsAuth: false
          tlsAuthWithCACert: false
        # <string> json object of data that will be encrypted.
        secureJsonData:
          tlsCACert: "..."
          tlsClientCert: "..."
          tlsClientKey: "..."
        version: 1
        # <bool> allow users to edit datasources from the UI.
        editable: true
      - name: Kuma
        uid: kuma
        editable: true
        type: kumahq-kuma-datasource
        url: {{.KumaCpApiAddress}}
        jsonData:
          prometheusDataSourceId: "1"
      - name: Jaeger
        type: jaeger
        access: proxy
        editable: true
        uid: jaeger
        url: {{.JaegerAddress}}
        jsonData:
          tracesToLogs:
            datasourceUid: loki
            tags: ["node_id"]
      - name: Loki
        type: loki
        access: proxy
        editable: true
        uid: loki
        url: {{.LokiAddress}}
        jsonData:
          derivedFields:
            - datasourceUid: jaeger
              matcherRegex: '"([0-9a-f]{16})"'
              name: "traceId"
              url: '$${__value.raw}'
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: provisioning-dashboards
  namespace: {{ .Namespace }}
  labels:
    app: grafana
data:
  dashboards.yaml: |
    apiVersion: 1

    providers:
    - name: 'Prometheus'
      orgId: 1
      folder: ''
      type: file
      disableDeletion: false
      editable: true
      options:
        path: /etc/grafana/provisioning/dashboards
{{ $namespace := .Namespace }}
{{ range $index, $dashboard := .Dashboards }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: provisioning-dashboards-{{ $index }}
  namespace: {{ $namespace }}
  labels:
    app: grafana
data:
{{ $dashboard.FileName | indent 2 }}: |
{{ $dashboard.Content | replace "${DS_PROMETHEUS}" "Prometheus" | indent 4 }}
---
{{ end }}
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app: grafana
  name: grafana
  namespace: {{ .Namespace }}
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    app: grafana
  name: grafana-clusterrole
rules: []
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: grafana-clusterrolebinding
  labels:
    app: grafana
subjects:
  - kind: ServiceAccount
    name: grafana
    namespace: {{ .Namespace }}
roleRef:
  kind: ClusterRole
  name: grafana-clusterrole
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: grafana
  namespace: {{ .Namespace }}
  labels:
    app: grafana
rules:
  - apiGroups:      ['extensions']
    resources:      ['podsecuritypolicies']
    verbs:          ['use']
    resourceNames:  [grafana]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: grafana
  namespace: default
  labels:
    app: grafana
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: grafana
subjects:
  - kind: ServiceAccount
    name: grafana
    namespace: {{ .Namespace }}
---
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: {{ .Namespace }}
  labels:
    app: grafana
spec:
  type: ClusterIP
  ports:
    - name: service
      port: 80
      protocol: TCP
      targetPort: 3000
  selector:
    app: grafana
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: {{ .Namespace }}
  labels:
    app: grafana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: grafana
        kuma.io/sidecar-injection: enabled
      annotations:
        checksum/config: 4fbce6ca7985bb33289922e68acc9af246f301cf9650f061fbcd0155925665df
        checksum/dashboards-json-config: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b
        checksum/sc-dashboard-provider-config: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b
        checksum/secret: 281444758252a4bdd272546732dfb8e2be87be71b795d2aadc3726e3524f63e3
        traffic.kuma.io/exclude-outbound-ports-for-uids: tcp:80,443:1472;udp:53:1472 # needed when running kuma CNI
    spec:
      serviceAccountName: grafana
      securityContext:
        fsGroup: 472
        runAsUser: 1472
      initContainers:
        - name: init-plugins
          image: alpine
          command: [ '/bin/sh', '-c', 'wget -O /tmp/kuma.zip https://github.com/kumahq/kuma-grafana-datasource/releases/download/v0.1.1/kumahq-kuma-datasource-0.1.1.zip && unzip -o /tmp/kuma.zip -d /var/lib/grafana/plugins/ && rm /tmp/kuma.zip']
          volumeMounts:
            - name: plugins-volume
              mountPath: /var/lib/grafana/plugins
      containers:
        - name: grafana
          image: "grafana/grafana:8.5.2"
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: config
              mountPath: "/etc/grafana/grafana.ini"
              subPath: grafana.ini
              readOnly: true
            - name: storage
              mountPath: "/var/lib/grafana"
            - name: provisioning-datasource
              mountPath: /etc/grafana/provisioning/datasources
              readOnly: true
            - name: provisioning-dashboards
              mountPath: /etc/grafana/provisioning/dashboards
              readOnly: true
            - name: plugins-volume
              mountPath: /var/lib/grafana/plugins
              readOnly: true
          ports:
            - name: service
              containerPort: 80
              protocol: TCP
            - name: grafana
              containerPort: 3000
              protocol: TCP
          livenessProbe:
            failureThreshold: 10
            httpGet:
              path: /api/health
              port: 3000
            initialDelaySeconds: 60
            timeoutSeconds: 30
          readinessProbe:
            httpGet:
              path: /api/health
              port: 3000
          resources:
            {}
          securityContext:
            runAsUser: 472
      volumes:
        - name: config
          configMap:
            name: grafana
        - name: provisioning-datasource
          configMap:
            name: provisioning-datasource
        - name: provisioning-dashboards
          projected:
            sources:
              - configMap:
                  name: provisioning-dashboards
{{ range $index, $dashboard := .Dashboards }}
              - configMap:
                  name: provisioning-dashboards-{{ $index }}
{{ end }}
        - name: storage
          emptyDir: {}
        - name: plugins-volume
          emptyDir: {}
